#include "CSonicAnmation.h"
#include <QDebug>
#include <QTime>

CSonicAnmation::CSonicAnmation(QWidget *parent) : QWidget(parent)
{
    qsrand(QTime::currentTime().msec()); //随机种子 为随机颜色做准备
}


void CSonicAnmation::setData(QVector<int> &vecData)
{
    if(m_vecSonic.size() > 2){
        m_vecSonic.takeLast();
    }
    m_vecSonic.append(vecData);

    update();
}

void CSonicAnmation::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event)
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing,true); //开启抗锯齿


    //描边画笔
    painter.setPen(QPen(QBrush(),0));

    //00坐标变换到左侧中间位置
    painter.translate(0,height()/2);
    //    painter.drawPoint(0,0); 画坐标原点

    foreach (QVector<int> vecData, m_vecSonic) {
        painter.setBrush(QBrush(randLineGradient())); //随机渐变填充
        painter.drawPath(calcCublic(vecData,painter));
    }
}

QPainterPath CSonicAnmation::calcCublic(QVector<int> vecData, QPainter &painter)
{
    Q_UNUSED(painter) //调试画锚点坐标用到

    m_nSpan = this->width() / vecData.size(); //计算每一节的宽度
    //计算手柄和锚点坐标
    QVector<StCubic> vecCubic;
    vecCubic.resize(vecData.size()*2);

    for (int i = 0; i < vecData.count(); i++) {
        //手柄1坐标
        QPointF ptHandle(m_nSpan * (i+1) - m_nSpan /2,((double)vecData.at(i)/100.00) * this->height());//第一个手柄  另一个手柄等于锚点
        QPointF ptAnchor(m_nSpan * (i+1),0); //锚点
        vecCubic[i] = StCubic(ptHandle,ptAnchor,ptAnchor);
        //        qDebug()<<"手柄D："<<ptHandle<<"锚点D:"<<i<<ptAnchor;

        //锚点坐标
        ptHandle.setY(-ptHandle.y());
        ptAnchor.setX(ptAnchor.x() - m_nSpan);
        vecCubic[vecCubic.size() -1 - i] = StCubic(ptHandle,ptAnchor,ptAnchor);//手柄2坐标和锚点相同
        //        qDebug()<<"手柄U："<<ptHandle<<"锚点U:"<<vecCubic.size() -1 - i<<ptAnchor;
    }

    randX(vecCubic);


    //勾勒贝塞尔曲线
    QPainterPath pathSonic(QPoint(0,0));
    for(int i = 0; i < vecCubic.size(); i++) {
        StCubic stCubic = vecCubic.at(i);
        pathSonic.cubicTo(stCubic.ptfHandle1,stCubic.ptfAnchor,stCubic.ptfAnchor);
        //调试显示手柄和锚点 不要删除
        //        painter.drawText(stCubic.ptfHandle1,QString("手柄%1").arg(i));
        //        painter.drawEllipse(stCubic.ptfHandle1,3,3);

        //        QPointF ptf(stCubic.ptfAnchor);
        //        ptf.setY(i < m_vecCubic.size()/2 ? -10 : 10);
        //        painter.drawText(ptf,QString("锚点 %1").arg(i));
        //        painter.drawRect(QRect(stCubic.ptfAnchor.toPoint(),QSize(3,3)));
    }

    return pathSonic;
}

void CSonicAnmation::randX(QVector<StCubic> &vecCubic)
{
    qsrand(QTime::currentTime().msec());

    for(int i = 0; i < vecCubic.size()/2 - 1; i++){
        //让锚点x坐标保持一定的随机性 看起来不那么机械
        int nOffsetX = (qrand() % m_nSpan) * 0.4; //X坐标随机偏移40%  可自由设置
        nOffsetX = nOffsetX & 1 ? -nOffsetX : nOffsetX;
        //qDebug()<<"随机数："<<nOffsetX;

        //设置对应的锚点随机偏移
        int nIndexDown = vecCubic.size() - (i+2);
        int nIndexUp = i;
        vecCubic[nIndexDown].ptfAnchor.setX( vecCubic[nIndexDown].ptfAnchor.x() + nOffsetX);
        vecCubic[nIndexUp].ptfAnchor.setX(vecCubic[nIndexUp].ptfAnchor.x() + nOffsetX);

        //qDebug()<<"锚点Down:"<<nIndexDown<<"="<<"锚点Up:"<<nIndexUp;
    }

}

QColor CSonicAnmation::randColor()
{
    //    int nS = qrand() % 255; //随机透明度
    //    int nR = qrand() % 255; //随机红色
    //    int nG = qrand() % 255; //随机绿色
    //    int nB = qrand() & 255; //随机蓝色

    //    return QColor(nS,nR,nG,nB);

    //随机浅色
    QColor colorRand;
    colorRand.setHsv(qrand() % 360,255,255,150); //随机色相 固定饱和度、明度、透明度  保持颜色为浅色

    return colorRand;
}

QLinearGradient CSonicAnmation::randLineGradient()
{
    QLinearGradient linearGradient(0, 0, this->width(), 0);//初始化，设置开始和结束点
    linearGradient.setColorAt(0.0, randColor());
    linearGradient.setColorAt(0.5, randColor());
    linearGradient.setColorAt(1.0, randColor());
    return linearGradient;
}
